#include <iostream>
#include <stdlib.h>
#include <windows.h>
#include <conio.h>

using namespace std;

const char* ver="1.1";

char* help[]= {"-?","-help","/?","/help","\\?","\\help"};
char* version[]= {"-v","-version","/v","/version","\\v","\\version"};
char* poweroff[]= {"-s","-shutdown","/s","/shutdown","\\s","\\shutdown"};
char* reboot[]= {"-r","-reboot","/r","/reboot","\\r","\\reboot"};
char* hour[]= {"-h","-hour","/h","/hour","\\h","\\hour"};
char* minute[]= {"-m","-minute","/m","/minute","\\m","\\minute"};
char* second[]= {"-ss","-second","/ss","/second","\\ss","\\second"};
char* tim[]= {"-t","-time","/t","/time","\\t","\\time"};
char* cancel[]= {"-c","-cancel","/c","/cancel","\\c","\\cancel"};

char* GetFilename(char *p)
{
    int x=strlen(p);
    char ch='\\';
    char *q=strrchr(p,ch);
    return q;
}

void setAutoRun()
{
    HKEY hKey;
    LPCSTR strRegPath = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";
    if (RegOpenKeyEx(HKEY_CURRENT_USER, strRegPath, 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS)
    {
        TCHAR szModule[_MAX_PATH];
        GetModuleFileName(NULL, szModule, _MAX_PATH);
        RegSetValueEx(hKey,"power", 0, REG_SZ, (const BYTE*)(LPCSTR)szModule, strlen(szModule));
        RegCloseKey(hKey);
    }
    else
    {
        cout<<"Warn:Fail to modify reg info."<<endl;
    }
}

char* removeAt(char* s,int index)
{
    int length=strlen(s)-1;
    for(int i=index; i<length; ++i)
        s[i]=s[i+1];
    return s;
}

bool compare1(char* str,char* pattern)
{
    int l1=strlen(str);
    int l2=strlen(pattern);
    int length=l1>l2?l1:l2;
    for(int i=0; i<length; ++i)
        if(str[i]!=pattern[i])
            return false;
    return true;
}

bool comparen(char* str,char** patterns,int length)
{
    for(int i=0; i<length; ++i)
        if(compare1(str,patterns[i]))
            return true;
    return false;
}

bool isnum(char* str)
{
    int length=strlen(str);
    for(int i=0; i<length; ++i)
        if(str[i]<'0'||str[i]>'9')
            return false;
    return true;
}

void onHelp()
{
    cout<<"               Power "<<ver<<" help"<<endl;
    cout<<"Information zone-------------"<<endl;
    cout<<"    -? :display help details."<<endl;
    cout<<"    -v :display version info."<<endl<<endl;
    cout<<"Function zone----------------"<<endl;
    cout<<"    -s :shutdown."<<endl;
    cout<<"    -r :reboot."<<endl;
    cout<<"    -c :cancel."<<endl;
    cout<<"Configuration zone-----------"<<endl<<endl;
    cout<<"    -h :set hours."<<endl;
    cout<<"    -m :set minutes."<<endl;
    cout<<"    -ss:set seconds."<<endl;
    cout<<"    -t [hh] [mm] [ss] :set time."<<endl<<endl;
    cout<<"Example----------------------"<<endl;
    cout<<"power -s -h 2 -m 30 -ss 30"<<endl;
    cout<<"  =power -s -t 2 30 30"<<endl;
    cout<<"  =system will shutdown after 2:30:30"<<endl;
    cout<<endl<<"This software has super chicken power."<<endl;
}

void onVersion()
{
    cout<<"Power "<<ver<<endl;
    cout<<"This software has super chicken power."<<endl;
}

int main(int argc,char *argv[])
{
    int h=0,m=0,s=0,total=0;
    bool shutdownFlag=false;
    bool rebootFlag=false;
    // debug
    //cout<<"debug mode"<<""<<endl<<endl;

    // Detect arguments.
    if(1==argc)
    {
        cout<<"No arguments detected. Please use power -? to see help."<<endl;
        exit(1);
    }
    for(int i=1; i<argc; ++i)
    {
        if(comparen(argv[i],cancel,sizeof(cancel)/sizeof(char*)))
        {
            system("shutdown -a");
            cout<<"Canceled."<<endl;
            exit(0);
        }
        if(comparen(argv[i],help,sizeof(help)/sizeof(char*)))
        {
            onHelp();
            continue;
        }
        if(comparen(argv[i],version,sizeof(version)/sizeof(char*)))
        {
            onVersion();
            continue;
        }
        if(comparen(argv[i],poweroff,sizeof(poweroff)/sizeof(char*)))
        {
            shutdownFlag=true;
            continue;
        }
        if(comparen(argv[i],reboot,sizeof(reboot)/sizeof(char*)))
        {
            rebootFlag=true;
            continue;
        }
        if(comparen(argv[i],hour,sizeof(hour)/sizeof(char*)))
        {
            if(!isnum(argv[i+1]))
            {
                cout<<"Error:expect number at argument "<<i+1<<endl;
                cout<<"Use power -? to see help."<<endl;
                exit(2);
            }
            h=atoi(argv[++i]);
            continue;
        }
        if(comparen(argv[i],minute,sizeof(minute)/sizeof(char*)))
        {
            if(!isnum(argv[i+1]))
            {
                cout<<"Error:expect number at argument "<<i+1<<endl;
                cout<<"Use power -? to see help."<<endl;
                exit(2);
            }
            m=atoi(argv[++i]);
            continue;
        }
        if(comparen(argv[i],second,sizeof(second)/sizeof(char*)))
        {
            if(!isnum(argv[i+1]))
            {
                cout<<"Error:expect number at argument "<<i+1<<endl;
                cout<<"Use power -? to see help."<<endl;
                exit(2);
            }
            s=atoi(argv[++i]);
            continue;
        }
        if(comparen(argv[i],tim,sizeof(tim)/sizeof(char*)))
        {
            // power -s -t 1 30 0
            // argc=5
            // i=1
            if(i+3>=argc)
            {
                cout<<"Error:expect more arguments."<<endl;
                cout<<"Use power -? to see help."<<endl;
                exit(3);
            }
            if(!isnum(argv[i+1]))
            {
                cout<<"Error:expect number at argument "<<i+1<<endl;
                cout<<"Use power -? to see help."<<endl;
                exit(2);
            }
            h=atoi(argv[++i]);
            if(!isnum(argv[i+1]))
            {
                cout<<"Error:expect number at argument "<<i+1<<endl;
                cout<<"Use power -? to see help."<<endl;
                exit(2);
            }
            m=atoi(argv[++i]);
            if(!isnum(argv[i+1]))
            {
                cout<<"Error:expect number at argument "<<i+1<<endl;
                exit(2);
            }
            s=atoi(argv[++i]);
            continue;
        }
    }
    char cmd[100];
    if(shutdownFlag)
    {
        strcpy(cmd,"shutdown -s -t ");
    }
    if(rebootFlag)
    {
        strcpy(cmd,"shutdown -r -t ");
    }
    if(shutdownFlag||rebootFlag)
    {
        total=h*3600+m*60+s;
        if(0==total)
        {
            char confirm;
            cout<<"Do you really mean to execute RIGHT NOW?[Y/n]";
            cin>>confirm;
            if('n'==confirm||'N'==confirm)
            {
                cout<<"Break."<<endl;
                exit(0);
            }
        }
        char t[10];
        itoa(total,t,10);
        strcat(cmd,t);
        system(cmd);
        cout<<"Your system will shutdown/reboot after "<<h<<" hour(s) "<<m<<" minute(s) "<<s<<" second(s)."<<endl;
        exit(0);
    }
    return 0;
}
